package com.cskaoyan.wx.controller;

import com.cskaoyan.bean.User;
import com.cskaoyan.bo.LoginBO;
import com.cskaoyan.realm.MallToken;
import com.cskaoyan.realm.MobileToken;
import com.cskaoyan.service.UserManagementService;
import com.cskaoyan.utils.UserUtils;
import com.cskaoyan.vo.BaseRespVo;
import com.cskaoyan.vo.UserVO;
import com.cskaoyan.wx.bo.Mobile;
import com.cskaoyan.wx.bo.WxUserBO;
import com.cskaoyan.wx.bo.WxUserResetBO;
import com.cskaoyan.wx.service.FileService;
import com.cskaoyan.wx.vo.WxIfo;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.io.Serializable;
import java.security.NoSuchAlgorithmException;
import java.util.Date;

@RestController
@RequestMapping("wx/auth/")
public class WxAuthController {

    @Autowired
    private UserManagementService userManagementService;

    @Autowired
    FileService fileService;

    @PostMapping("login")
    public BaseRespVo authLogin(@RequestBody @Valid LoginBO loginBO) throws NoSuchAlgorithmException {
        String username = loginBO.getUsername();
        String password = loginBO.getPassword();
        // String md5Password = Md5Util.getMd5(password);

        Subject subject = SecurityUtils.getSubject();
        MallToken mallToken = new MallToken(username, password, "wx");
        try {
            subject.login(mallToken);
        } catch (AuthenticationException e) {
            return BaseRespVo.fail("用户名或密码不正确", 402);
        }

        Session session = subject.getSession();
        Date lastAccessTime = session.getLastAccessTime();
        String host = session.getHost();
        User user= userManagementService.getUserByName(username);
        userManagementService.updateLoginIpAndLoginTime(host, lastAccessTime, username);

        session.setAttribute("username", username);
        session.setAttribute("userId",user.getId());

        WxIfo wxIfo = new WxIfo();

        WxIfo.UserInfoBean userInfoBean = new WxIfo.UserInfoBean();
        userInfoBean.setNickName(user.getNickname());
        userInfoBean.setAvatarUrl(user.getAvatar());
        wxIfo.setUserInfo(userInfoBean);

        String sessionId = (String) session.getId();
        wxIfo.setToken(sessionId);

        long timeout = session.getTimeout();
        Date date = new Date();
        date = new Date(date.getTime() + timeout);
        wxIfo.setTokenExpire(date);

        return BaseRespVo.ok(wxIfo);
    }

    @PostMapping("logout")
    public BaseRespVo logout() {
        Subject subject = SecurityUtils.getSubject();
        subject.logout();
        return BaseRespVo.ok();
    }

    @PostMapping("regCaptcha")
    public BaseRespVo regCaptcha(@RequestBody Mobile mobile){
        String randomCaptcha = UserUtils.getRandomCaptcha();
        System.out.println(randomCaptcha);
        fileService.sendMsg(mobile.getMobile(), randomCaptcha);
        Subject subject = SecurityUtils.getSubject();

        subject.getSession().setAttribute("captcha", randomCaptcha);
        String seesionId = (String) subject.getSession().getId();
        WxIfo wxIfo = new WxIfo();
        wxIfo.setToken(seesionId);
        return BaseRespVo.ok(wxIfo);
    }

    @PostMapping("register")
    public BaseRespVo register(@RequestBody WxUserBO wxUserBO){
        String userCaptcha = wxUserBO.getCode();
        Subject subject = SecurityUtils.getSubject();
        String captcha = (String) subject.getSession().getAttribute("captcha");

        if (!userCaptcha.equals(captcha)){
            return BaseRespVo.fail("验证码错误",703);
        }

        // 验证手机号是否已经存在
        MobileToken mobileToken = new MobileToken(wxUserBO.getMobile(), "default", "mobile");
        subject.login(mobileToken);


        // 添加用户到数据库, 用户已存在则抛出异常
        Integer userId = null;
        try {
            userId = userManagementService.addAUser(wxUserBO);
        } catch (DataAccessException e) {
            return BaseRespVo.fail("用户名已存在", 703);
        }

        // 对新用户进行认证授权
        MallToken token = new MallToken(wxUserBO.getUsername(), wxUserBO.getPassword(), "wx");

        subject.login(token);

        // 返回新用户的信息
        WxIfo wxIfo = new WxIfo();
        WxIfo.UserInfoBean userInfoBean = new WxIfo.UserInfoBean();
        userInfoBean.setNickName(UserUtils.getRandomNickname(wxUserBO.getUsername()));
        userInfoBean.setAvatarUrl(UserUtils.getDefaultAvatarUrl());
        wxIfo.setUserInfo(userInfoBean);

        Session session = subject.getSession();
        session.setAttribute("userId",userId);
        String sessionId = (String) session.getId();
        wxIfo.setToken(sessionId);

        long timeout = session.getTimeout();
        Date date = new Date();
        date = new Date(date.getTime() + timeout);
        wxIfo.setTokenExpire(date);

        return BaseRespVo.ok(wxIfo);
    }

    @PostMapping("reset")
    public BaseRespVo reset(@RequestBody WxUserResetBO wxUserResetBO){
        // 校验验证码
        String userCaptcha = wxUserResetBO.getCode();
        Subject subject1 = SecurityUtils.getSubject();
        String captcha = (String) subject1.getSession().getAttribute("captcha");
        if (!userCaptcha.equals(captcha)){
            return BaseRespVo.fail("验证码错误",703);
        }

        // 校验手机号在数据库中存在
        int count = userManagementService.getUserByMobile(wxUserResetBO.getMobile());
        if (count == 0){
            return BaseRespVo.fail("该账号不存在, 请检查你的手机号是否正确",703);
        }

        userManagementService.resetPassword(wxUserResetBO);

        return BaseRespVo.ok("密码重置成功");
    }
}
